# Manipulating the DOM
# Selecting Elements
You have access to all of an element’s properties. You can modify
- the contents of the element
- attributes
- properties
# .querySelector()
and .querySelectorAll()
querySelector()
only returns the first element that matches the specified CSS selectors.- To return all the matches, use the
querySelectorAll()
:- It returns a NodeList object, representing elements that match the specified CSS selector(s). Looks like an Array, but it's not
- If no matches are found, null is returned.
Inside the brackets the same rules apply as with any CSS selectors:
#
for IDs.
(dot) for classes[ ]
for attributes, etc.
// find and return the element with an ID of "header"
document.querySelector('#header');
// find and return the first element with the class "header"
document.querySelector('.header');
// find and return the first <header> element
document.querySelector('header');
Select by attribute:
<p aria-hidden="true">Lorem Ipsum ...</p>
document.querySelector("[aria-hidden]");
document.querySelector('[aria-hidden="true"]');
Select by Order:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
// Select Item 2 and Item 3
document.querySelector('li + li');
Multiple selectors:
<h1>Header</h1>
<h2>Sub Header</h2>
document.querySelector('h1, h2');
- .querySelector() method on MDN (opens new window)
- .querySelectorAll() method on MDN (opens new window)
- NodeList on MDN (opens new window)
# Usage:
Apply this method on the whole DOM or on a selected part of the DOM.
// Get the first match:
document.querySelector()
// Get all matches:
document.querySelectorAll()
// Match on children:
const navigation = document.querySelector("#nav")
navigation.querySelector(‘li')
# Shorthands
# .getElementById()
Often the best way to select a single element.
const footer = document.getElementById('footer');
'footer'
, not '#footer'
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Selecting Multiple Elements At Once:
Beware of the S: getElementsBy...
# .getElementsByClassName()
document.getElementsByClassName('brand-color');
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
# .getElementsByTagName()
-> aktive Node-List: adapts, when the page-content changes and it is faster than:querySelectorAll()
(static Node-List)
document.getElementsByTagName('p');
Also:document.getElementByTagName()
# Special Accessors
Every Node object has special accessors. These are properties of DOM elements and read-only.
element.childNodes
- returns a collection of a node's child nodes, as a NodeList objectelement.firstChild
element.lastChild
element.parentNode
element.closest('p')
-Traverses all children of the parent in search for a match.children
- return a list of the element’s children and returnnull
if the element has no children.previousSibling/nextSibling
# An Element's (Text) Content
# .innerHTML
Each element has an .innerHTML
property. This represents the markup of the element's content. We can use this to:
- get an element's (and all of its descendants!) HTML content
- set an element's HTML content
It retuns: it looks like a string. Technically, what it returns is called a DOMString.
- https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
# .outerHTML
rarely used - Represents the HTML element itself, as well as its children.
<h1 id="pick-me">Greetings To <span>All</span>!</h1>
const innerResults = document.querySelector('#pick-me').innerHTML;
console.log(innerResults); // logs the string: "Greetings To <span>All</span>!"
const outerResults = document.querySelector('#pick-me').outerHTML;
console.log(outerResults); // logs the string: "<h1 id="pick-me">Greetings To <span>All</span>!</h1>"
- https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML
# .textContent
The .textContent
property will set and return the text content of an element and all its descendants
nanodegreeCard.textContent = "I will be the updated text!";
Passing any text that looks like HTML to the .textContent
property will still be displayed as text. It will not be displayed as HTML when the element is rendered.
# .innerText
.innerText
will get the visible text of the element.
If CSS is used to hide any text inside that element,
.innerText
will not return that text, while.textContent
will return it.innerText
will also honor changes to things like capitalization.You probably want to use
.textContent
since that will return all of the text no matter what.Article: The poor, misunderstood innerText (opens new window)
# Creating new elements
# .createElement
The .createElement()
method is a method on the document
object. It just creates an an empty element with no inner HTML. It doesn't add it to the DOM.
In order add it to the web page, you must assign it to be the child of an element that already exists on the DOM. We call this process appending.appendChild()
const div = document.createElement('div')
div.innerHTML = '<p>Text</p>'
// or
div.innerText = 'Text'
# .createTextNode
Not recommendet: it's faster and easier to just update the element's text with the .textContent
property.
var h = document.createElement("h1")
var t = document.createTextNode("Hello World");
h.appendChild(t);
const myPara = document.createElement('p');
const textOfParagraph = document.createTextNode('I am the text for the paragraph!');
myPara.appendChild(textOfParagraph);
document.body.appendChild(myPara);
the code below will provide the exact same result:
const myPara = document.createElement('p');
myPara.textContent = 'I am the text for the paragraph!';
document.body.appendChild(myPara);
- https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode
# Adding and replacing nodes
# .appendChild()
etc.
method | Description |
---|---|
element.appendChild(newElement) | nests a new element inside another element. - will move an element from its current position to the new position!- https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild |
document.body.appendChild(newElement) | nests a new element inside the body tag |
document.insertBefore(newElement, referenceElement) | puts a new element just before the other element |
document.replaceChild(newElement, oldElement) | replaces one element with another |
# .insertAdjacentHTML()
To insert HTML text anywhere around an element. It needs to be called on a parent element with two arguments:
- the location of the HTML
- the HTML text that is going to be inserted
The first argument to this method will let us insert the new HTML in one of four different locations
beforebegin
– inserts the HTML text as a previous siblingafterbegin
– inserts the HTML text as the first childbeforeend
– inserts the HTML text as the last childafterend
– inserts the HTML text as a following sibling<!-- beforebegin --> <p> <!-- afterbegin --> Existing text/HTML content <!-- beforeend --> </p> <!-- afterend -->
The second argument text parses the specified text as HTML and inserts the resulting nodes into the DOM tree at a specified position.
const mainHeading = document.querySelector('#main-heading');
const htmlTextToAdd = '<h2>Skydiving is fun!</h2>';
mainHeading.insertAdjacentHTML('afterend', htmlTextToAdd);
# Removing nodes
method | Description |
---|---|
parent.remove(element) | removes an element directly .remove() MDN (opens new window) |
parent.removeChild(element) | removes an element removeChild MDN (opens new window) - drawback to the .removeChild() method: it requires access to parent. Workaround: mainHeading.parentElement.removeChild(mainHeading); |
element.innerHTML = '' | empties an element - deletes all children as well as all listeners |
# Style Page Content
# .style
Modifying an Element's Style Attribute
.style
provides access to the inline style of that HTML tag.
Good for setting one style at a time, but not great for controlling multiple styles.
does not implement a hyphen such as
background-color
, but rather camel case notationbackgroundColor
. MDN reference page (opens new window)
let blueElement = document.querySelector('.blue');
blueElement.style.backgroundColor = 'blue';
chaining syntax would also work:
document.querySelector('.blue').style.fontFamily = 'Roboto';
- style docs (opens new window)
- Article: Using dynamic styling information (opens new window)
- DOM methods to control styling (opens new window)
# .style.cssText
**Adding Multiple Styles At Once **
use .style.cssText
to set multiple CSS styles at once!
const mainHeading = document.querySelector('h1');
mainHeading.style.cssText = 'color: blue; background-color: orange; font-size: 3.5em';
write the CSS styles just as you would in a stylesheet; so you write font-size
rather than fontSize
.
- https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/cssText
# .setAttribute()
Setting An Element's Attributes
Another way to set styles for an element is to use the .setAttribute()
method:
const mainHeading = document.querySelector('h1');
mainHeading.setAttribute('style', 'color: blue; background-color: orange; font-size: 3.5em;');
not just for styling page elements. You can use this method to set any attribute for an element. If you want to give an element an ID, you can do that!:
const mainHeading = document.querySelector('h1');
// add an ID to the heading's sibling element
mainHeading.nextElementSibling.setAttribute('id', 'heading-sibling');
// use the newly added ID to access that element
document.querySelector('#heading-sibling').style.backgroundColor = 'red';
- https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute
# Other Properties
# Change Attributes of an Element
-> eveything inide the tag
.attributes
gives a list of all attributes
.getAttribute("href")
returns the value of a single attribute
.setAttribute("href", "www.google.com")
sets the attribute
hasAttribute()
removeAttribute()
# .hidden
Allows to hide the Element by assigning it as true or false:
document.getElementById('sign').hidden = true;
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/hidden
# Accessing an Element's Classes
# .classList
.classList
is by far the most helpful property of the bunch,helps to keep your CSS styling out of your JavaScript code.
Use the
.classList
property more than any other.
const listOfClasses = mainHeading.classList;
Returns a DOMTokenList (opens new window). Similar to an Array.
Has a number of properties. Some of the most popularly used ones are:
.add()
- to add a class to the list.remove()
- to remove a class from the list.toggle()
- to add the class if it doesn't exists or remove it from the list if it does already exist.contains()
- returns a boolean based on if the class exists in the list or not
element.classList.add('cool-class', ‘second-class’)
element.classList.remove('bad-class')
element.classList.contains('another-class')
# .className
returns a space-separated string of all of the element's classes.
This isn't the most ideal format, it makes it hard to add or remove individual classes. -> would have to it convert into array.
// store the list of classes in a variable
const listOfClasses = mainHeading.className;
mainHeading.className = "im-the-new-class";
The above code erases any classes that were originally in the element's class
attribute and replaces it